home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / text / manipulation / snap164.lha / snap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-30  |  41.0 KB  |  1,257 lines

  1. /***********************************************\
  2. *                                               *
  3. *                     Snap                      *
  4. *         © Mikael Karlsson 1988-1991           *
  5. *                                               *
  6. \***********************************************/
  7. /* Auto: make "CCEXTRA=-wq -qf"
  8. */
  9.  
  10. #if __SASC
  11. #include "snap.h"
  12. #endif
  13.  
  14. #ifdef SNAPREXX
  15. #include "minrexx.h"
  16. #endif SNAPREXX
  17. #include <stdio.h>
  18.  
  19. #define ARGVAL() ((*argv && *++(*argv)) || (--argc && *++argv))
  20.  
  21. static char Version[] = "$VER: 1.63 © 1991 Mikael Karlsson & Absolut Software\n";
  22.  
  23. BOOL Kick36;
  24.  
  25. /* signals */
  26. LONGBITS startsignal, insertsignal, cancelsignal;
  27. LONGBITS donesignal, movesignal, clicksignal;
  28. LONGBITS timersignal, initsignal, cwsignal, ticksignal;
  29. ULONG startsignum = -1L;
  30. ULONG insertsignum = -1L;
  31. ULONG cancelsignum = -1L;
  32. ULONG donesignum = -1L;
  33. ULONG movesignum = -1L;
  34. ULONG clicksignum = -1L;
  35. ULONG initsignum = -1L;
  36. ULONG cwsignum = -1L;
  37. ULONG ticksignum = -1L;
  38. ULONG WaitSignal;
  39.  
  40. /* program */
  41. struct SnapRsrc *SnapRsrc = NULL;
  42. struct Task *MyTask;
  43.  
  44. /* Snap state machine */
  45. WORD action;
  46. WORD state;
  47.  
  48. /* clipboard */
  49. struct IOClipReq *ClipReq = NULL;
  50. struct MsgPort *ClipPort = NULL;
  51.  
  52. /* timer device */
  53. struct MsgPort *TimerPort = NULL;
  54. struct timerequest MyTR;
  55.  
  56. /* input device */
  57. struct MsgPort *inputDevPort = NULL;
  58. struct Interrupt handlerStuff;
  59. struct IOStdReq *inputRequestBlock = NULL;
  60. struct InputEvent SimEvent;
  61. WORD textqual;
  62. WORD gfxqual;
  63. WORD insertkey;
  64. WORD cwkey;
  65. WORD modinsert;
  66.  
  67. UBYTE *CharData = NULL;
  68. UBYTE TrueUnderscore;
  69.  
  70. /* console */
  71. struct MsgPort *ConPort = NULL;
  72. struct IOStdReq *ConIOR = NULL;
  73. struct KeyMap keymap;
  74.  
  75. /* windows */
  76. #ifdef SNAPGFX
  77. struct MsgPort *Sharedport = NULL;
  78. SHORT Sharedrefs;
  79. IMPORT struct Window *ControlWindow;
  80. struct Window *SaveWin = NULL;
  81. IMPORT struct Gadget SaveGad;
  82. IMPORT struct Gadget NameGad;
  83. struct GfxSnap *SwapGS = NULL;
  84. IMPORT struct StringInfo TranspSI;
  85. IMPORT struct Image ActiveDiskImage;
  86. IMPORT struct Image InactiveDiskImage;
  87. IMPORT struct Image ActiveClipImage;
  88. IMPORT struct Image InactiveClipImage;
  89. #endif SNAPGFX
  90. IMPORT UBYTE *WindowTitle;
  91.  
  92. /* libraries */
  93. IMPORT struct ExecBase *SysBase;
  94. struct IntuitionBase *IntuitionBase = NULL;
  95. struct GfxBase       *GfxBase = NULL;
  96. #if 0
  97. struct LayersBase    *LayersBase = NULL;
  98. struct DiskFontBase  *DiskfontBase = NULL;
  99. #endif
  100. struct Library *    LayersBase = NULL;
  101. struct Library *    DiskfontBase = NULL;
  102.  
  103. struct Library       *IconBase = NULL;
  104. #ifdef SNAPGFX
  105. #ifdef REQLIB
  106. struct ReqBase       *ReqBase = NULL;
  107. #endif REQLIB
  108. #ifdef ASLLIB
  109. struct Library       *AslBase = NULL;
  110. #endif ASLLIB
  111. #endif SNAPGFX
  112.  
  113. /* graphics */
  114. struct Screen *theScreen;
  115. struct Layer *theLayer;
  116. struct RastPort rp, TempRp, MyRP;
  117. struct BitMap TempBM, MyBM;
  118. UBYTE *TempRaster = NULL;
  119.  
  120. #ifdef SNAPGFX
  121. #ifdef REQLIB
  122. struct ReqFileRequester *NameFR = NULL;
  123. #endif REQLIB
  124. #ifdef ASLLIB
  125. struct FileRequester *AslNameFR = NULL;
  126. #endif ASLLIB
  127. char SaveName[DSIZE+FCHARS+2];
  128. BPTR SnapFile;
  129. #endif SNAPGFX
  130.  
  131. /* ARexx stuff */
  132. #ifdef SNAPREXX
  133. ULONG rexxsignal;
  134. IMPORT struct rexxCommandList rcl[];
  135. WORD disp();
  136. #endif SNAPREXX
  137.  
  138. #ifdef AZTEC_C
  139. int stricmp(char *s1, char *s2 )
  140. {
  141.    char c1, c2;
  142.  
  143.    while (*s1 && *s2) {
  144.       if ((c1 = *(s1++)) >= 'a' && c1 <= 'z') {
  145.          c1 -= 32;
  146.       }
  147.       if ((c2 = *(s2++)) >= 'a' && c2 <= 'z') {
  148.          c2 -= 32;
  149.       }
  150.  
  151.       if ( c1 != c2 ) {
  152.          return( c1 - c2 );
  153.       }
  154.    }
  155.  
  156.    return( *s1 - *s2 );
  157. }
  158.  
  159.  
  160. int strnicmp(char *s1, char *s2, int n)
  161. {
  162.    char c1, c2;
  163.  
  164.    while (*s1 && *s2 && --n > 0) {
  165.       c1 = *(s1++);
  166.       c2 = *(s2++);
  167.  
  168.       if (c1 >= 'a' && c1 <= 'z') {
  169.          c1 -= 32;
  170.       }
  171.       if (c2 >= 'a' && c2 <= 'z') {
  172.          c2 -= 32;
  173.       }
  174.  
  175.       if (c1 != c2) {
  176.          return(c1 - c2);
  177.       }
  178.    }
  179.  
  180.    c1 = *s1;
  181.    c2 = *s2;
  182.  
  183.    if (c1 >= 'a' && c1 <= 'z') {
  184.       c1 -= 32;
  185.    }
  186.    if (c2 >= 'a' && c2 <= 'z') {
  187.       c2 -= 32;
  188.    }
  189.  
  190.    return(c1 - c2);
  191. }
  192. #endif
  193.  
  194. LONG dectoint(REGISTER char *str)
  195. {
  196.     REGISTER long val = 0;
  197.     REGISTER char c;
  198.     while ((c = *str) >= '0' && c <= '9') {
  199.         val = (((val<<2)+val)<<1) + c-'0';
  200.         str++;
  201.     }
  202.     return(val);
  203. }
  204.  
  205. LONG hextoint(REGISTER char *str)
  206. {
  207.     REGISTER long val = 0;
  208.     REGISTER char c;
  209.  
  210.     if (!strnicmp(str, "0x", 2)) {
  211.         str += 2;
  212.     }
  213.     while (c = *str) {
  214.         val <<= 4;
  215.         val |= (c & 15) + ((c>='0' && c<='9') ? 0 : 9);
  216.         str++;
  217.     }
  218.     return(val);
  219. }
  220.  
  221. WORD insertcount;
  222.  
  223. VOID InsertAscii(ULONG ascii)
  224. {
  225.     if (insertcount == 1) {   /* Time for second char */
  226.           /* Not necessary to patch here but it guarantees
  227.              that all inserted chars end up in the same window. */
  228.         SafePatch();
  229.     }
  230.     if (AsciiToInputEvent(ascii, &SimEvent, &keymap)) {
  231.         DoIO((struct IORequest *)inputRequestBlock);
  232.         if (SnapRsrc->chardelay) {
  233.             MyTR.tr_node.io_Command = TR_ADDREQUEST;
  234.             MyTR.tr_time.tv_micro = SnapRsrc->chardelay;
  235.             MyTR.tr_time.tv_secs = 0;
  236.             DoIO((struct IORequest *)&MyTR);
  237.         }
  238.     }
  239.     ++insertcount;
  240. }
  241.  
  242. #ifdef SNAPGFX
  243. VOID GadText(struct Gadget *Gad, char *Str, LONG Len)
  244. {
  245.     char temp[256];
  246.     SHORT i;
  247.  
  248.     SetDrMd(ControlWindow->RPort, JAM2);
  249.     SetAPen(ControlWindow->RPort, 0L);
  250.     RectFill(ControlWindow->RPort, (LONG)Gad->LeftEdge, (LONG)Gad->TopEdge,
  251.       (LONG)Gad->LeftEdge + Gad->Width - 1, (LONG)Gad->TopEdge + Gad->Height - 1);
  252.     SetAPen(ControlWindow->RPort, 1L);
  253.     SetBPen(ControlWindow->RPort, 0L);
  254.     Move(ControlWindow->RPort,
  255.       (LONG)Gad->LeftEdge + 1,
  256.       (LONG)Gad->TopEdge + ControlWindow->RPort->Font->tf_Baseline + 1);
  257.     if (TextLength(ControlWindow->RPort, Str, Len) > Gad->Width) {
  258.         i = Len;
  259.         strncpy(temp, Str, i - 3);
  260.         strcat(temp, "...");
  261.         while (TextLength(ControlWindow->RPort, temp, (LONG)i) > Gad->Width) {
  262.             --i;
  263.             temp[i] = '\0';
  264.             temp[i-3] = '.';
  265.         }
  266.         Text(ControlWindow->RPort, temp, (LONG)i);
  267.     } else {
  268.         Text(ControlWindow->RPort, Str, Len);
  269.     }
  270. }
  271.  
  272. VOID SwapColorMap(struct GfxSnap *GS)
  273. {
  274.     struct ViewPort *vp = &GS->window->WScreen->ViewPort;
  275.     LONG i = (GS->viewmode & HAM ? 16 : 1L << GS->depth);
  276.     ULONG col;
  277.  
  278.     while (i-- && (col = GetRGB4(vp->ColorMap, i)) != -1L) {
  279.         SetRGB4(vp, i,
  280.           (LONG)GS->rgb[i][0] >> 4,
  281.           (LONG)GS->rgb[i][1] >> 4,
  282.           (LONG)GS->rgb[i][2] >> 4);
  283.         GS->rgb[i][0] = ((col >> 8) & 0x0f) << 4;
  284.         GS->rgb[i][1] = ((col >> 4) & 0x0f) << 4;
  285.         GS->rgb[i][2] = ((col >> 0) & 0x0f) << 4;
  286.     }
  287. }
  288.  
  289. VOID CheckWindowMsgs()
  290. {
  291.     struct IntuiMessage *Msg;
  292.     struct IntuiMessage *QdMsg = NULL;
  293.     ULONG Class;
  294.     USHORT Code;
  295.     struct Window *Win;
  296.     struct Gadget *Gad;
  297.  
  298.     while (Sharedport &&
  299.       (QdMsg || (Msg = (struct IntuiMessage *)GetMsg(Sharedport)))) {
  300.         if (QdMsg) {
  301.             Msg = QdMsg;
  302.             QdMsg = NULL;
  303.         }
  304.         Class = Msg->Class;
  305.         Code  = Msg->Code;
  306.         Win   = Msg->IDCMPWindow;
  307.         Gad   = (struct Gadget *)Msg->IAddress;
  308.         ReplyMsg((struct Message *)Msg);
  309.         switch (Class) {
  310.             case CLOSEWINDOW: {
  311.                 struct GfxSnap *GS = NULL;
  312.                 if (Win == ControlWindow) {
  313.                     ControlWindow = NULL;
  314.                     if (SaveWin) {
  315.                         SetWindowTitles(SaveWin, (char *)WindowTitle, (char *)-1);
  316.                         SaveWin = NULL;
  317.                     }
  318.                 } else {
  319.                     GS = (struct GfxSnap *)Win->UserData;
  320.                     FreePlanes(&GS->BM, GS->width, GS->height);
  321.                     if (Win == SaveWin || Sharedrefs == 1) {
  322.                         if (ControlWindow) {
  323.                             OffGadget(&SaveGad, ControlWindow, NULL);
  324.                         }
  325.                         SaveWin = NULL;
  326.                     }
  327.                 }
  328.                 closesharedwindow(Win);
  329.                 if (GS) {
  330.                     Kill(GS);
  331.                 }
  332.                 break;
  333.             }
  334.             case NEWSIZE: {
  335.                 AdjustSize((struct GfxSnap *)Win->UserData);
  336.                 break;
  337.             }
  338.             case MOUSEMOVE: {
  339.                   /* Collapse all consecutively queued MOUSEMOVE msgs */
  340.                 while ((QdMsg = (struct IntuiMessage *)GetMsg(Sharedport))
  341.                   && (QdMsg->Class == MOUSEMOVE)) {
  342.                     ReplyMsg((struct Message *)QdMsg);
  343.                 }
  344.                 SyncGS((struct GfxSnap *)Win->UserData);
  345.                 break;
  346.             }
  347.             case REFRESHWINDOW: {
  348.                 BeginRefresh(Win);
  349.                 SyncGS((struct GfxSnap *)Win->UserData);
  350.                 EndRefresh(Win, 1L);
  351.             }
  352.             case INACTIVEWINDOW: {
  353.                 if (Win != ControlWindow) {
  354.                     struct GfxSnap *GS;
  355.                     GS = (struct GfxSnap *)Win->UserData;
  356.                     if (SwapGS) {
  357.                         SwapColorMap(SwapGS);
  358.                         SwapGS = NULL;
  359.                     }
  360.                     GS->DiskGad.GadgetRender = (APTR)&InactiveDiskImage;
  361.                     GS->ClipGad.GadgetRender = (APTR)&InactiveClipImage;
  362.                     RefreshGList(&GS->DiskGad, GS->window, NULL, -1);
  363.                 }
  364.                 break;
  365.             }
  366.             case ACTIVEWINDOW: {
  367.                 if (Win != ControlWindow) {
  368.                     struct GfxSnap *GS;
  369.                     GS = (struct GfxSnap *)Win->UserData;
  370.                     GS->DiskGad.GadgetRender = (APTR)&ActiveDiskImage;
  371.                     GS->ClipGad.GadgetRender = (APTR)&ActiveClipImage;
  372.                     RefreshGList(&GS->DiskGad, GS->window, NULL, -1);
  373.                 }
  374.                 break;
  375.             }
  376.             case GADGETUP: {
  377.                 switch (Gad->GadgetID) {
  378.                     case VPROP:
  379.                     case HPROP: {
  380.                         SyncGS((struct GfxSnap *)Win->UserData);
  381.                         break;
  382.                     }
  383.                     case SAVEGAD: {
  384. savepic:
  385.                         if (SaveWin) {
  386.                             WORD success = 0;
  387.                             struct GfxSnap *GS;
  388.                             GS = (struct GfxSnap *)SaveWin->UserData;
  389.  
  390.                             if (SaveName[0] == '\0') {
  391.                                 DisplayBeep(NULL);
  392.                                 ActivateGadget(&NameGad, ControlWindow, NULL);
  393.                                 break;
  394.                             }
  395.                             SnapFile = (BPTR)Open((char *)SaveName, MODE_NEWFILE);
  396.                             if (SnapFile) {
  397.                                 struct CBFHandle CBFH;
  398.                                 CBFH.Type = CBFFILE;
  399.                                 CBFH.Handle.File = SnapFile;
  400.                                 success = SaveGS(GS, &CBFH);
  401.                                 Close(SnapFile);
  402.                             }
  403.                             if (success) {
  404.                                 SetWindowTitles(ControlWindow, "Saved ok", (char *)-1);
  405.                             } else {
  406.                                 DeleteFile((char *)SaveName);
  407.                                 DisplayBeep(NULL);
  408.                                 SetWindowTitles(ControlWindow, "Save failed", (char *)-1);
  409.                             }
  410.                         }
  411.                         break;
  412.                     }
  413.                     case NAMEGAD: { /* Should only happen with Req */
  414. #ifdef ASLLIB
  415.                         if ((AslNameFR) && (Kick36)) {
  416.                             if (RequestFile(AslNameFR)) {
  417.                                 strncpy(SaveName, AslNameFR->rf_Dir, sizeof(SaveName));
  418.                                 AddPart((UBYTE *)SaveName,
  419.                                         (UBYTE *)AslNameFR->rf_File,
  420.                                         sizeof(SaveName));
  421.                             }
  422.                             GadText(&NameGad, SaveName, (LONG)strlen(SaveName));
  423.                         }
  424. #else
  425.                         if (0) {}
  426. #endif ASLLIB
  427. #ifdef REQLIB
  428.                         else if (NameFR) {
  429.                             NameFR->Title = "Save picture as...";
  430.                             NameFR->PathName = SaveName;
  431.                             NameFR->Window = ControlWindow;
  432.                             (VOID)BruceFileRequester(NameFR);
  433.                             GadText(&NameGad, SaveName, (LONG)strlen(SaveName));
  434.                         }
  435. #endif REQLIB
  436.                         break;
  437.                     }
  438.                     case DISKGAD: {
  439.                         struct GfxSnap *GS;
  440.                         if (!ControlWindow && !OpenCW()) {
  441.                             DisplayBeep(NULL);
  442.                             break;
  443.                         }
  444.                         if (Win == SaveWin) {
  445.                             goto savepic;
  446.                         }
  447.                         if (SaveWin) {
  448.                             SetWindowTitles(SaveWin, (char *)WindowTitle, (char *)-1);
  449.                             GS = (struct GfxSnap *)SaveWin->UserData;
  450.                             RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
  451.                         } else {
  452.                             GadText(&SaveGad, "Save", 4L);
  453.                             OnGadget(&SaveGad, ControlWindow, NULL);
  454.                         }
  455.                         SaveWin = Win;
  456.                         SetWindowTitles(SaveWin, "Selected", (char *)-1);
  457.                         GS = (struct GfxSnap *)SaveWin->UserData;
  458.                         RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
  459.                         break;
  460.                     }
  461.                     case CLIPGAD: {
  462.                         struct CBFHandle CBFH;
  463.                         struct GfxSnap *GS = (struct GfxSnap *)Win->UserData;
  464.  
  465.                         CBFH.Type = CBFCLIP;
  466.                         CBFH.Handle.ClipReq = ClipReq;
  467.                         if (!SaveGS(GS, &CBFH)) {
  468.                             DisplayBeep(NULL);
  469.                         }
  470.                         break;
  471.                     }
  472.                     default: {
  473.                         break;
  474.                     }
  475.                 }
  476.                 break;
  477.             }
  478.             case MOUSEBUTTONS: {
  479.                 if (Win != ControlWindow) {
  480.                     if (Code == SELECTDOWN && !SwapGS) {
  481.                         SwapGS = (struct GfxSnap *)Win->UserData;
  482.                         SwapColorMap(SwapGS);
  483.                     } else if (Code == SELECTUP && SwapGS) {
  484.                         SwapColorMap(SwapGS);
  485.                         SwapGS = NULL;
  486.                     }
  487.                 }
  488.                 break;
  489.             }
  490.             default: {
  491.                 break;
  492.             }
  493.         }
  494.     }
  495.     if (QdMsg) {
  496.         ReplyMsg((struct Message *)QdMsg);
  497.     }
  498. }
  499. #endif SNAPGFX
  500.  
  501. #define WriteStr(str) fputs(str, stdout)
  502. #define WriteChar(char) fputc(char, stdout)
  503.  
  504. struct QualPair {
  505.     char *str;
  506.     WORD val;
  507. };
  508.  
  509. struct QualPair Qualifiers[] = {
  510.     { "LSHIFT",    IEQUALIFIER_LSHIFT },
  511.     { "RSHIFT",    IEQUALIFIER_RSHIFT },
  512.     { "CONTROL",   IEQUALIFIER_CONTROL },
  513.     { "LALT",      IEQUALIFIER_LALT },
  514.     { "RALT",      IEQUALIFIER_RALT },
  515.     { "LCOMMAND",  IEQUALIFIER_LCOMMAND },
  516.     { "RCOMMAND",  IEQUALIFIER_RCOMMAND },
  517.     { "MIDBUTTON", IEQUALIFIER_MIDBUTTON }
  518. };
  519.  
  520. WORD ParseQual(char *quals)
  521. {
  522.     char *temp;
  523.     WORD i;
  524.     char oldc;
  525.     WORD qual = 0;
  526.  
  527.     if (('0' >= *quals) && (*quals <= '9')) {
  528.         return hextoint(quals);
  529.     }
  530.  
  531.     while (*quals) {
  532.         temp = quals;
  533.         while ((oldc = *quals) && oldc != '+') {
  534.             quals++;
  535.         }
  536.         *quals = 0;
  537.         for (i = 0; i < (sizeof(Qualifiers) / sizeof(Qualifiers[0])); i++) {
  538.             if (!stricmp(temp, Qualifiers[i].str)) {
  539.                 qual |= Qualifiers[i].val;
  540.                 break;
  541.             }
  542.         }
  543.         if (*quals = oldc) {
  544.             quals++;
  545.         }
  546.     }
  547.     return qual;
  548. }
  549.  
  550. WORD SetAltFont(char *str)
  551. {
  552.     struct TextAttr ta;
  553.     struct TextFont *NewFont;
  554.     char temp[33];
  555.     WORD pos = 0;
  556.  
  557.     if (strlen(str) <= 32) {
  558.  
  559.         strcpy(temp, str);
  560.         ta.ta_Name = (UBYTE *)temp;
  561.         while (temp[pos] != '\0' && temp[pos] != '/') {
  562.             ++pos;
  563.         }
  564.         if (temp[pos] == '\0') {     /* No size */
  565.             ta.ta_YSize = 8;
  566.         } else {
  567.             temp[pos] = '\0';
  568.             ta.ta_YSize = dectoint(&temp[pos + 1]);
  569.         }
  570.         if (pos > 5) {
  571.             if (stricmp(&temp[pos - 5], ".font")) {
  572.                 strcpy(&temp[pos], ".font");
  573.             }
  574.         } else {
  575.             strcpy(&temp[pos], ".font");
  576.         }
  577.         ta.ta_Style = 0;
  578.         ta.ta_Flags = 0;
  579.         NewFont = SmartOpenFont(&ta);
  580.         if (NewFont) {
  581.             if (SnapRsrc->AlternateFont) {
  582.                 CacheSync(SnapRsrc->AlternateFont);
  583.                 CloseFont(SnapRsrc->AlternateFont);
  584.             }
  585.             SnapRsrc->AlternateFont = NewFont;
  586.         }
  587.     }
  588.     return (NewFont ? 1 : 0);
  589. }
  590.  
  591. struct SnapRsrc DefaultRsrc = {
  592.     { NULL, NULL, NT_RESOURCE, 0, SNAPRSRC },   /* Node */
  593.     NULL,                                       /* Task */
  594.     52,                                         /* Priority */
  595.     IEQUALIFIER_RCOMMAND,                       /* Graphics qualifier */
  596.     IEQUALIFIER_LCOMMAND,                       /* Text qualifier */
  597.     0x17,                                       /* Insert key */
  598.     0x11,                                       /* Control Window key */
  599.     { '>', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Prepend */
  600.     {   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Append */
  601.     TRUEUNDERSCORE,                             /* Flags */
  602.     0,                                          /* Char delay */
  603.     0,                                          /* Line delay */
  604.     0x7777,                                     /* Crawl pattern */
  605.     UNIT_FRAME,                                 /* Starting unit */
  606.     1,                                          /* Frame mask */
  607.     '?',                                        /* Bad char */
  608.     10,                                         /* Cache size */
  609.     1,                                          /* Extra line spacing */
  610.     { NULL, NULL, NULL },                       /* MinList, Cached windows */
  611.     NULL                                        /* Alternate font */
  612. };
  613.  
  614. #ifdef LATTICE
  615. VOID main(int argc, char **argv)
  616. #else
  617. WORD main(int argc, char **argv)
  618. #endif
  619. {
  620.     WORD create = 0, usage = 0;
  621.  
  622. #ifdef AZTEC_C
  623.     Enable_Abort = 0;
  624. #endif AZTEC_C
  625.  
  626.     Kick36 = (SysBase->LibNode.lib_Version >= 36 ? 1 : 0);
  627.  
  628.     if (!(SnapRsrc = (struct SnapRsrc *)OpenResource(SNAPRSRC))) {
  629.         create = 1;
  630.         SnapRsrc = Create(SnapRsrc);
  631.         CopyMem((char *)&DefaultRsrc, (char *)SnapRsrc, sizeof(struct SnapRsrc));
  632.         SnapRsrc->Task = FindTask(NULL);
  633.         NewList((struct List *)&SnapRsrc->CachedWindows);
  634.         AddResource((struct MiscResource *)SnapRsrc);
  635.     }
  636.  
  637.       /* Open libraries since we might need them when parsing arguments */
  638.     if (!OpenLibs()) {
  639.         goto exitpoint;
  640.     }
  641.  
  642.     if (!argc) {    /* WB Startup */
  643.         if (!create) {     /* Second time from WB -- Remove Snap */
  644.             Signal(SnapRsrc->Task, SIGBREAKF_CTRL_C);
  645.             goto exitpoint;
  646.         } else if (IconBase) {   /* Is it possible to be started from Workbench
  647.                                     without icon.library being available. */
  648.             BPTR olddir;
  649.             struct WBStartup *wbstartup;
  650.             struct DiskObject *diskobject;
  651.             char *val;
  652.  
  653.             wbstartup = (struct WBStartup *)argv;
  654.             olddir = CurrentDir(wbstartup->sm_ArgList[0].wa_Lock);
  655.             diskobject = GetDiskObject(wbstartup->sm_ArgList[0].wa_Name);
  656.             if (!diskobject) {
  657.                 goto skipargs;
  658.             }
  659.             if (val = FindToolType(diskobject->do_ToolTypes, "PRIORITY")) {
  660.                 WORD pri = dectoint(val);
  661.                 if (pri>50 && pri<128) {
  662.                     SnapRsrc->Priority = pri;
  663.                 }
  664.             }
  665.             if (val = FindToolType(diskobject->do_ToolTypes, "TEXTQUAL")) {
  666.                 if (!(SnapRsrc->textqual = ParseQual(val))) {
  667.                     SnapRsrc->textqual = IEQUALIFIER_LCOMMAND;
  668.                 }
  669.             }
  670.             if (val = FindToolType(diskobject->do_ToolTypes, "GFXQUAL")) {
  671.                 if (!(SnapRsrc->gfxqual = ParseQual(val))) {
  672.                     SnapRsrc->gfxqual = IEQUALIFIER_RCOMMAND;
  673.                 }
  674.             }
  675.             if (val = FindToolType(diskobject->do_ToolTypes, "INSERTKEY")) {
  676.                 SnapRsrc->insertkey = hextoint(val);
  677.             }
  678.             if (val = FindToolType(diskobject->do_ToolTypes, "CWKEY")) {
  679.                 SnapRsrc->cwkey = hextoint(val);
  680.             }
  681.             if (val = FindToolType(diskobject->do_ToolTypes, "APPEND")) {
  682.                 strncpy(&SnapRsrc->Append[0], val, 16);
  683.             }
  684.             if (val = FindToolType(diskobject->do_ToolTypes, "PREPEND")) {
  685.                 strncpy(&SnapRsrc->Prepend[0], val, 16);
  686.             }
  687.             if (val = FindToolType(diskobject->do_ToolTypes, "CHARDELAY")) {
  688.                 SnapRsrc->chardelay = dectoint(val);
  689.             }
  690.             if (val = FindToolType(diskobject->do_ToolTypes, "LINEDELAY")) {
  691.                 SnapRsrc->linedelay = dectoint(val) * 1000;
  692.             }
  693.             if (val = FindToolType(diskobject->do_ToolTypes, "CRAWLPTRN")) {
  694.                 SnapRsrc->CrawlPtrn = hextoint(val);
  695.             }
  696.             if (val = FindToolType(diskobject->do_ToolTypes, "XEROX")) {
  697.                 SnapRsrc->flags |= XEROX;
  698.             }
  699.             if (val = FindToolType(diskobject->do_ToolTypes, "NOXEROX")) {
  700.                 SnapRsrc->flags &= ~XEROX;
  701.             }
  702.             if (val = FindToolType(diskobject->do_ToolTypes, "EARLYPATCH")) {
  703.                 SnapRsrc->flags |= EARLYPATCH;
  704.             }
  705.             if (val = FindToolType(diskobject->do_ToolTypes, "NOEARLYPATCH")) {
  706.                 SnapRsrc->flags &= ~EARLYPATCH;
  707.             }
  708.             if (val = FindToolType(diskobject->do_ToolTypes, "STARTUNIT")) {
  709.                 if (*val == '1') {
  710.                     SnapRsrc->StartUnit = UNIT_CHAR;
  711.                 } else {
  712.                     SnapRsrc->StartUnit = UNIT_FRAME;
  713.                 }
  714.             }
  715.             if (val = FindToolType(diskobject->do_ToolTypes, "TRUEUNDERSCORE")) {
  716.                 SnapRsrc->flags |= TRUEUNDERSCORE;
  717.             }
  718.             if (val = FindToolType(diskobject->do_ToolTypes, "FAKEUNDERSCORE")) {
  719.                 SnapRsrc->flags &= ~TRUEUNDERSCORE;
  720.             }
  721.             if (val = FindToolType(diskobject->do_ToolTypes, "JOINLONG")) {
  722.                 SnapRsrc->flags |= JOINLONG;
  723.             }
  724.             if (val = FindToolType(diskobject->do_ToolTypes, "NOJOINLONG")) {
  725.                 SnapRsrc->flags &= ~JOINLONG;
  726.             }
  727.             if (val = FindToolType(diskobject->do_ToolTypes, "SIMPLEREFRESH")) {
  728.                 SnapRsrc->flags |= SIMPLEREFRESH;
  729.             }
  730.             if (val = FindToolType(diskobject->do_ToolTypes, "SMARTREFRESH")) {
  731.                 SnapRsrc->flags &= ~SIMPLEREFRESH;
  732.             }
  733.             if (val = FindToolType(diskobject->do_ToolTypes, "PLANEMASK")) {
  734.                 SnapRsrc->FrameMask = hextoint(val);
  735.             }
  736.             if (val = FindToolType(diskobject->do_ToolTypes, "CACHESIZE")) {
  737.                 SnapRsrc->CacheSize = dectoint(val);
  738.             }
  739.             if (val = FindToolType(diskobject->do_ToolTypes, "LEADING")) {
  740.                 SnapRsrc->Leading = dectoint(val);
  741.             }
  742.             if (val = FindToolType(diskobject->do_ToolTypes, "BADCHAR")) {
  743.                 SnapRsrc->BadChar = (*val ? *val : 0);
  744.             }
  745.             if (val = FindToolType(diskobject->do_ToolTypes, "ALTFONT")) {
  746.                 SetAltFont(val);
  747.             }
  748.             FreeDiskObject(diskobject);
  749.             goto skipargs;
  750.         }
  751.     }
  752.  
  753.     if (create) {
  754.         WriteStr("Snap");
  755.         WriteStr(&Version[5]);
  756.     }
  757.  
  758.     for (argc--, argv++; argc > 0; argc--, argv++) {
  759.         if (**argv == '-') { /* Argument coming up */
  760.             switch(*++(*argv)) {
  761.                 case 'p': priority: {  /* Priority */
  762.                     if (ARGVAL()) {
  763.                         WORD pri = dectoint(*argv);
  764.                         if (pri>50 && pri<128) {
  765.                             SnapRsrc->Priority = pri;
  766.                         }
  767.                     } else {
  768.                         usage = 1;
  769.                     }
  770.                     break;
  771.                 }
  772.                 case 't': textqual: {
  773.                     if (ARGVAL()) {
  774.                         if (!(SnapRsrc->textqual = ParseQual(*argv))) {
  775.                             SnapRsrc->textqual = IEQUALIFIER_LCOMMAND;
  776.                         }
  777.                     } else {
  778.                         usage = 1;
  779.                     }
  780.                     break;
  781.                 }
  782. #ifdef SNAPGFX
  783.                 case 'g': gfxqual: {
  784.                     if (ARGVAL()) {
  785.                         if (!(SnapRsrc->gfxqual = ParseQual(*argv))) {
  786.                             SnapRsrc->gfxqual = IEQUALIFIER_RCOMMAND;
  787.                         }
  788.                     } else {
  789.                         usage = 1;
  790.                     }
  791.                     break;
  792.                 }
  793. #endif SNAPGFX
  794.                 case 'i': insertkey: {
  795.                     if (ARGVAL()) {
  796.                         SnapRsrc->insertkey = hextoint(*argv);
  797.                     } else {
  798.                         usage = 1;
  799.                     }
  800.                     break;
  801.                 }
  802. #ifdef SNAPGFX
  803.                 case 'w': cwkey: {
  804.                     if (ARGVAL()) {
  805.                         SnapRsrc->cwkey = hextoint(*argv);
  806.                     } else {
  807.                         usage = 1;
  808.                     }
  809.                     break;
  810.                 }
  811. #endif SNAPGFX
  812.                 case 'c': chardelay: {
  813.                     if (ARGVAL()) {
  814.                         SnapRsrc->chardelay = dectoint(*argv) * 1000;
  815.                     } else {
  816.                         usage = 1;
  817.                     }
  818.                     break;
  819.                 }
  820.                 case 'l': linedelay: {
  821.                     if (ARGVAL()) {
  822.                         SnapRsrc->linedelay = dectoint(*argv) * 1000;
  823.                     } else {
  824.                         usage = 1;
  825.                     }
  826.                     break;
  827.                 }
  828.                 case 'a': crawlptrn: {
  829.                     if (ARGVAL()) {
  830.                         SnapRsrc->CrawlPtrn = hextoint(*argv);
  831.                     } else {
  832.                         usage = 1;
  833.                     }
  834.                     break;
  835.                 }
  836.                 case 'X': noxerox: {
  837.                     SnapRsrc->flags &= ~XEROX;
  838.                     break;
  839.                 }
  840.                 case 'x': xerox: {
  841.                     SnapRsrc->flags |= XEROX;
  842.                     break;
  843.                 }
  844.                 case 'E': noearlypatch: {
  845.                     SnapRsrc->flags &= ~EARLYPATCH;
  846.                     break;
  847.                 }
  848.                 case 'e': earlypatch: {
  849.                     SnapRsrc->flags |= EARLYPATCH;
  850.                     break;
  851.                 }
  852.                 case 'R': fakeunderscore: {
  853.                     SnapRsrc->flags &= ~TRUEUNDERSCORE;
  854.                     break;
  855.                 }
  856.                 case 'r': realunderscore: {
  857.                     SnapRsrc->flags |= TRUEUNDERSCORE;
  858.                     break;
  859.                 }
  860.                 case 'J': nojoinlong: {
  861.                     SnapRsrc->flags &= ~JOINLONG;
  862.                     break;
  863.                 }
  864.                 case 'j': joinlong: {
  865.                     SnapRsrc->flags |= JOINLONG;
  866.                     break;
  867.                 }
  868.                 case 'A': append: {
  869.                     char *dest = &SnapRsrc->Append[0];
  870.                     if ((*argv && *++(*argv)) || (--argc && ++argv)) { /* "" is ok */
  871.                         char *src = *argv;
  872.                         WORD i = 16;
  873.                         while (*src && i--) {
  874.                             *dest++ = *src++;
  875.                         }
  876.                         *dest = '\0';
  877.                     } else {
  878.                         usage = 1;
  879.                     }
  880.                     break;
  881.                 }
  882.                 case 'P': prepend: {
  883.                     char *dest = &SnapRsrc->Prepend[0];
  884.                     if ((*argv && *++(*argv)) || (--argc && ++argv)) { /* "" is ok */
  885.                         char *src = *argv;
  886.                         WORD i = 16;
  887.                         while (*src && i--) {
  888.                             *dest++ = *src++;
  889.                         }
  890.                         *dest = '\0';
  891.                     } else {
  892.                         usage = 1;
  893.                     }
  894.                     break;
  895.                 }
  896.                 case 'u': startunit: {
  897.                     if (ARGVAL()) {
  898.                         if (**argv == '1') {
  899.                             SnapRsrc->StartUnit = UNIT_CHAR;
  900.                         } else {
  901.                             SnapRsrc->StartUnit = UNIT_FRAME;
  902.                         }
  903.                     } else {
  904.                         usage = 1;
  905.                     }
  906.                     break;
  907.                 }
  908.                 case 'b': planemask: {
  909.                     if (ARGVAL()) {
  910.                         SnapRsrc->FrameMask = hextoint(*argv);
  911.                     } else {
  912.                         usage = 1;
  913.                     }
  914.                     break;
  915.                 }
  916. #ifdef SNAPGFX
  917.                 case 's': smartrefresh: {
  918.                     SnapRsrc->flags &= ~SIMPLEREFRESH;
  919.                     break;
  920.                 }
  921.                 case 'S': simplerefresh: {
  922.                     SnapRsrc->flags |= SIMPLEREFRESH;
  923.                     break;
  924.                 }
  925. #endif SNAPGFX
  926.                 case 'C': cachesize: {
  927.                     if (ARGVAL()) {
  928.                         SnapRsrc->CacheSize = dectoint(*argv);
  929.                     } else {
  930.                         usage = 1;
  931.                     }
  932.                     break;
  933.                 }
  934.                 case 'L': leading: {
  935.                     if (ARGVAL()) {
  936.                         SnapRsrc->Leading = dectoint(*argv);
  937.                     } else {
  938.                         usage = 1;
  939.                     }
  940.                     break;
  941.                 }
  942.                 case 'B': badchar: {
  943.                     if (ARGVAL()) {
  944.                         SnapRsrc->BadChar = dectoint(*argv);
  945.                     } else {
  946.                         usage = 1;
  947.                     }
  948.                     break;
  949.                 }
  950.                 case 'F': altfont: {
  951.                     if (ARGVAL()) {
  952.                         SetAltFont(*argv);
  953.                     } else {
  954.                         usage = 1;
  955.                     }
  956.                     break;
  957.                 }
  958.                 case 'Q':
  959.                 case 'q': quit: {
  960.                     if (create) {
  961.                         goto close;
  962.                     } else {
  963.                         Signal(SnapRsrc->Task, SIGBREAKF_CTRL_C);
  964.                         goto exitpoint;
  965.                     }
  966.                 }
  967.                 case '?': {
  968.                     usage = 1;
  969.                     break;
  970.                 }
  971.                 default: {
  972.                     WriteStr("Bad option: -");
  973.                     WriteChar((int)**argv);
  974.                     WriteStr(".\n");
  975.                     usage = 1;
  976.                     break;
  977.                 }
  978.             }
  979.         } else {
  980. #ifdef SNAPGFX
  981.             char *keyword = *argv;
  982.             *argv = NULL;
  983.             if (!stricmp(keyword, "PRIORITY")) {
  984.                 goto priority;                      /* Terrible, ain't it? */
  985.             } else if (!stricmp(keyword, "TEXTQUAL")) {
  986.                 goto textqual;
  987.             } else if (!stricmp(keyword, "GFXQUAL")) {
  988.                 goto gfxqual;
  989.             } else if (!stricmp(keyword, "INSERTKEY")) {
  990.                 goto insertkey;
  991.             } else if (!stricmp(keyword, "CWKEY")) {
  992.                 goto cwkey;
  993.             } else if (!stricmp(keyword, "PREPEND")) {
  994.                 goto prepend;
  995.             } else if (!stricmp(keyword, "APPEND")) {
  996.                 goto append;
  997.             } else if (!stricmp(keyword, "CHARDELAY")) {
  998.                 goto chardelay;
  999.             } else if (!stricmp(keyword, "LINEDELAY")) {
  1000.                 goto linedelay;
  1001.             } else if (!stricmp(keyword, "CRAWLPTRN")) {
  1002.                 goto crawlptrn;
  1003.             } else if (!stricmp(keyword, "XEROX")) {
  1004.                 goto xerox;
  1005.             } else if (!stricmp(keyword, "NOXEROX")) {
  1006.                 goto noxerox;
  1007.             } else if (!stricmp(keyword, "EARLYPATCH")) {
  1008.                 goto earlypatch;
  1009.             } else if (!stricmp(keyword, "NOEARLYPATCH")) {
  1010.                 goto noearlypatch;
  1011.             } else if (!stricmp(keyword, "TRUEUNDERSCORE")) {
  1012.                 goto realunderscore;
  1013.             } else if (!stricmp(keyword, "FAKEUNDERSCORE")) {
  1014.                 goto fakeunderscore;
  1015.             } else if (!stricmp(keyword, "JOINLONG")) {
  1016.                 goto joinlong;
  1017.             } else if (!stricmp(keyword, "NOJOINLONG")) {
  1018.                 goto nojoinlong;
  1019.             } else if (!stricmp(keyword, "SIMPLEREFRESH")) {
  1020.                 goto simplerefresh;
  1021.             } else if (!stricmp(keyword, "SMARTREFRESH")) {
  1022.                 goto smartrefresh;
  1023.             } else if (!stricmp(keyword, "STARTUNIT")) {
  1024.                 goto startunit;
  1025.             } else if (!stricmp(keyword, "PLANEMASK")) {
  1026.                 goto planemask;
  1027.             } else if (!stricmp(keyword, "CACHESIZE")) {
  1028.                 goto cachesize;
  1029.             } else if (!stricmp(keyword, "LEADING")) {
  1030.                 goto leading;
  1031.             } else if (!stricmp(keyword, "BADCHAR")) {
  1032.                 goto badchar;
  1033.             } else if (!stricmp(keyword, "ALTFONT")) {
  1034.                 goto altfont;
  1035.             } else if (!stricmp(keyword, "QUIT")) {
  1036.                 goto quit;
  1037.             } else if (stricmp(keyword, "?")) {
  1038.                 WriteStr("Bad switch/keyword: ");
  1039.                 WriteStr(keyword);
  1040.                 WriteStr(".\n");
  1041.             }
  1042. #endif SNAPGFX
  1043.             usage = 1;
  1044.         }
  1045.     }
  1046.  
  1047.     if (usage) {
  1048.         WriteStr("Usage:\n");
  1049. #ifdef SNAPGFX
  1050.         WriteStr(" snap -pNN -tQQ -gQQ -iXX -wXX -Pstr -Astr -cNN -lNN\n");
  1051.         WriteStr("   -aXXXX -x -X -e -E -uN -r -R -j -J -s -S -bXX -CNN\n");
  1052.         WriteStr("   -LNN -BNN -Ffont -Q\n");
  1053.         WriteStr(" or\n");
  1054.         WriteStr(" snap PRIORITY/K TEXTQUAL/K GFXQUAL/K INSERTKEY/K CWKEY/K\n");
  1055.         WriteStr("   PREPEND/K APPEND/K CHARDELAY/K LINEDELAY/K CRAWLPTRN/K\n");
  1056.         WriteStr("   XEROX/S NOXEROX/S EARLYPATCH/S NOEARLYPATCH/S STARTUNIT/K\n");
  1057.         WriteStr("   TRUEUNDERSCORE/S FAKEUNDERSCORE/S JOINLONG/S NOJOINLONG/S\n");
  1058.         WriteStr("   SIMPLEREFRESH/S SMARTREFRESH/S PLANEMASK/K CACHESIZE/K\n");
  1059.         WriteStr("   LEADING/K BADCHAR/K ALTFONT/K QUIT/S\n");
  1060. #else
  1061.         WriteStr(" snap -pNN -tQQ -iXX -Pstr -Astr -cNN -lNN\n");
  1062.         WriteStr("   -aXXXX -x -X -e -E -uN -r -R -j -J -bXX -CNN\n");
  1063.         WriteStr("   -LNN -BNN -Ffont -Q\n");
  1064. #endif SNAPGFX
  1065.         WriteStr("\n");
  1066.         WriteStr("S-Mail: Mikael Karlsson     | E-Mail: micke@slaka.sirius.se\n");
  1067.         WriteStr("        Lövsättersvägen 10  |         micke@slaka.UUCP\n");
  1068.         WriteStr("        S-585 98  LINKÖPING |         {mxvax|seismo}!sunic!liuida!slaka!micke\n");
  1069.         WriteStr("        Sweden              | Phone:  +46 (0)13 50479\n");
  1070.         goto exitpoint;
  1071.     }
  1072.  
  1073. skipargs:
  1074.     freopen("NIL:", "w", stdout);
  1075.  
  1076.     if (!create) {
  1077.           /* Tell him there are new settings available */
  1078.         Signal(SnapRsrc->Task, SIGBREAKF_CTRL_F);
  1079.         goto exitpoint;
  1080.     }
  1081.  
  1082.     if (!OpenStuff()) {
  1083.         goto close;
  1084.     }
  1085.  
  1086.     textqual = SnapRsrc->textqual;
  1087.     gfxqual = SnapRsrc->gfxqual;
  1088.     insertkey = SnapRsrc->insertkey;
  1089.     cwkey = SnapRsrc->cwkey;
  1090.     TrueUnderscore = SnapRsrc->flags & TRUEUNDERSCORE ? 1 : 0;
  1091. #ifdef SNAPGFX
  1092.     SaveName[0] = '\0';
  1093. #endif
  1094.  
  1095. #ifdef SNAPREXX
  1096.     rexxsignal = upRexxPort("SNAP", rcl, NULL, &disp);
  1097. #endif SNAPREXX
  1098.  
  1099.     /* This is what we're waiting for */
  1100.     WaitSignal = startsignal | insertsignal | initsignal | cancelsignal |
  1101. #ifdef SNAPREXX
  1102.                  rexxsignal |
  1103. #endif SNAPREXX
  1104.                  cwsignal | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F;
  1105.  
  1106.     FOREVER {
  1107.         REGISTER LONGBITS sig;
  1108.  
  1109.         sig = Wait(WaitSignal | timersignal
  1110. #ifdef SNAPGFX
  1111.             | (Sharedport ? (1L << Sharedport->mp_SigBit) : 0L)
  1112. #endif SNAPGFX
  1113.             );
  1114.  
  1115. #ifdef SNAPGFX
  1116.         CheckWindowMsgs();
  1117. #endif SNAPGFX
  1118.  
  1119. #ifdef SNAPREXX
  1120.         if (sig & rexxsignal) {
  1121.             dispRexxPort();
  1122.         }
  1123. #endif SNAPREXX
  1124.         if (sig & SIGBREAKF_CTRL_C) {
  1125.             /* This is my cue. Exit if there are no open windows depending on us */
  1126. #ifdef SNAPGFX
  1127.             if (Sharedrefs) {
  1128.                 DisplayBeep(NULL);
  1129.             } else
  1130. #endif SNAPGFX
  1131.             {
  1132.                 goto close;
  1133.             }
  1134.         }
  1135.         if (sig & SIGBREAKF_CTRL_F) {
  1136.             /* Hey, seems like there are new settings available. */
  1137.             textqual = SnapRsrc->textqual;
  1138.             gfxqual = SnapRsrc->gfxqual;
  1139.             insertkey = SnapRsrc->insertkey;
  1140.             cwkey = SnapRsrc->cwkey;
  1141.             TrueUnderscore = SnapRsrc->flags & TRUEUNDERSCORE ? 1 : 0;
  1142.         }
  1143.         if (sig & initsignal) {
  1144.             if (SnapRsrc->flags & (XEROX | EARLYPATCH)) {
  1145.                 SafePatch();               /* Patch dangerous functions */
  1146.             }
  1147.         }
  1148.         if (sig & cancelsignal) {
  1149.             SafeRestore();
  1150.         }
  1151.         if (sig & startsignal) { /* The handler wants a word in. */
  1152.             SafePatch();
  1153. #ifdef SNAPGFX
  1154.             if (action == snapgfx) {       /* Check user action */
  1155.                 HandleGfx();               /* Get the picture :-) */
  1156.             } else
  1157. #endif SNAPGFX
  1158.             if (action == snaptext && HandleChars()) {  /* Snap some chars */
  1159.                 if (SnapRsrc->flags & XEROX) {
  1160.                     sig |= insertsignal;
  1161.                 }
  1162.             } else {
  1163.                   /* Previous snap wasn't finished when this one started
  1164.                      or this snap failed. */
  1165.                 SetSignal(0L, movesignal | cancelsignal |
  1166.                   donesignal | clicksignal | ticksignal);
  1167.                 DisplayBeep(NULL);
  1168.                 action = noaction;
  1169.             }
  1170.             if (!(sig & insertsignal)) {
  1171.                 SafeRestore();             /* Layers unlocked - all safe */
  1172.             }
  1173.         }
  1174.  
  1175.         if (sig & insertsignal) {
  1176.             LONG i;
  1177.             struct Snap *Snap;
  1178.             ULONG ascii;
  1179.  
  1180.             action = insert;
  1181.             if (Snap = FetchClip()) {  /* Get clipboard data */
  1182.                   /* get the current keymap  */
  1183.                 ConIOR->io_Command =  CD_ASKDEFAULTKEYMAP;
  1184.                 ConIOR->io_Length  = sizeof (struct KeyMap);
  1185.                 ConIOR->io_Data    = (APTR) &keymap;
  1186.                 ConIOR->io_Flags   = 1;    /* no IOQuick   */
  1187.                 DoIO((struct IORequest *)ConIOR);
  1188.                   /* Set up an input request */
  1189.                 inputRequestBlock->io_Command = IND_WRITEEVENT;
  1190.                 inputRequestBlock->io_Flags   = 0L;
  1191.                 inputRequestBlock->io_Length  = (long)sizeof(struct InputEvent);
  1192.                 inputRequestBlock->io_Data    = (APTR)&SimEvent;
  1193.                   /* Translate chars in SnapSpace and insert them
  1194.                      into the input stream. */
  1195.                 insertcount = 0;
  1196.                 ascii = 13;  /* Simulate start of new line */
  1197.                 for (i = 0; Snap->Chars[i] && (action == insert); ++i) {
  1198.                     if (ascii == 13 && modinsert) {
  1199.                         int cnt = 0;
  1200.                         while (ascii = SnapRsrc->Prepend[cnt++]) {
  1201.                             InsertAscii(ascii);
  1202.                         }
  1203.                     }
  1204.  
  1205.                     ascii = Snap->Chars[i];
  1206.                     if (ascii == 10) {
  1207.                         if (modinsert) {
  1208.                             int cnt = 0;
  1209.                             while (ascii = SnapRsrc->Append[cnt++]) {
  1210.                                 InsertAscii(ascii);
  1211.                             }
  1212.                         }
  1213.                         ascii = 13;     /* WYSIWYG? Hah! */
  1214.                     }
  1215.                     InsertAscii(ascii);
  1216.                     if (ascii == 13 && SnapRsrc->linedelay) {
  1217.                         MyTR.tr_node.io_Command = TR_ADDREQUEST;
  1218.                         MyTR.tr_time.tv_micro = SnapRsrc->linedelay;
  1219.                         MyTR.tr_time.tv_secs = 0;
  1220.                         DoIO((struct IORequest *)&MyTR);
  1221.                     }
  1222.                 }
  1223.                 if (modinsert) {
  1224.                     int cnt = 0;
  1225.                     while (ascii = SnapRsrc->Append[cnt++]) {
  1226.                         InsertAscii(ascii);
  1227.                     }
  1228.                 }
  1229.                 SafeRestore();  /* "Depatch" */
  1230.                   /* Free memory given to us by FetchClip() */
  1231.                 FreeMem(Snap, Snap->Size);
  1232.             }
  1233.             action = noaction;
  1234.             modinsert = 0;
  1235.         }
  1236.  
  1237. #ifdef SNAPGFX
  1238.         if (sig & cwsignal) {
  1239.             if (!ControlWindow && !OpenCW()) {
  1240.                 DisplayBeep(NULL);
  1241.             }
  1242.         }
  1243. #endif SNAPGFX
  1244.     }
  1245.  
  1246. close:
  1247. #ifdef SNAPREXX
  1248.     dnRexxPort();
  1249. #endif SNAPREXX
  1250.     CloseStuff();  /* Guess what */
  1251. exitpoint:
  1252.     CloseLibs();
  1253. #ifdef AZTEC_C
  1254.     return 0;
  1255. #endif
  1256. }
  1257.